home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Code Resources / Jims CDEFs 1.50 / CDEF Source / source / cdefBar.c < prev    next >
Encoding:
Text File  |  1995-11-08  |  15.1 KB  |  539 lines  |  [TEXT/KAHL]

  1. //------------------------- © 1994-1995 by James G. Stout --------------------------
  2. // File        : cdefBar.c
  3. // Date        : May 2, 1994
  4. // Author    : Jim Stout
  5. //            :
  6. // Purpose    : A CDEF to implement a progress bar
  7. //            :
  8. //            : If you find a use for this, I'd love to know about it.  Bug reports
  9. //            : are always interesting.
  10. //            :
  11. //            : Internet    : JimS@WRQ.COM(work hours, PST)
  12. //            : AppleLink   : WRQ            (daily)
  13. //            : CompuServe  : 73240,2052    (weekly or so)
  14. //            : AOL         : JasG        (weekly or so)
  15. //            : eWorld      : Jim Stout    (weekly or so)
  16. //----------------------------------------------------------------------------------
  17. //#define _DEBUGCDEF 1        // comment out to build CDEF
  18.  
  19. #include "fatCDEF.h"
  20.  
  21. #include <Controls.h>
  22. #include <GestaltEqu.h>
  23. #include <LowMem.h>
  24. #include <Memory.h>
  25. #include <Palettes.h>
  26. #include <ToolUtils.h>
  27. #include <Types.h>
  28.  
  29. #include "colorCDEF.h"
  30. #include "miscCDEF.h"
  31.  
  32. #include "cdefBar.h"
  33.  
  34.  
  35. #ifdef _DEBUGCDEF
  36. pascal long CDmain (short varCode, ControlHandle theCtl, short message, long param);
  37.  
  38. pascal long CDmain (short varCode, ControlHandle theCtl, short message, long param)
  39. #else
  40.  
  41. //==================================================================================
  42. // CDEF entry point
  43. //==================================================================================
  44. pascal long main (short varCode, ControlHandle theCtl, short message, long param)
  45. #endif
  46. {
  47.     cdefHdl        hCdef;
  48.     SignedByte    cState, dState;
  49.     
  50. #include "fatEntry.c"
  51.  
  52.     cState = HGetState((Handle)theCtl);
  53.     HLock((Handle)theCtl);
  54.     if((**theCtl).contrlData) {
  55.         dState = HGetState((**theCtl).contrlData);
  56.         HLock((**theCtl).contrlData);
  57.     }
  58.     
  59.     switch(message) {
  60.         case initCntl:
  61.             hCdef = (cdefHdl)NewHandle(sizeof(cdefData));
  62.             if(hCdef) {
  63.                 StuffHex(&(**hCdef).thePat,"\pF0783C1E0F87C3E1");
  64.                 (**theCtl).contrlData = (Handle)hCdef;
  65.                 dState = HGetState((**theCtl).contrlData);
  66.                 HLock((**theCtl).contrlData);
  67.             }
  68.         break;
  69.         case dispCntl:
  70.             if((**theCtl).contrlData) {
  71.                 HUnlock((**theCtl).contrlData);
  72.                 DisposeHandle((**theCtl).contrlData);
  73.                 (**theCtl).contrlData = 0;
  74.             }
  75.         break;
  76.         case drawCntl:
  77.             if((*theCtl)->contrlVis) {
  78.                 if(varCode & roundBar)
  79.                     drawRoundEndBar(theCtl, varCode);
  80.                 else
  81.                     drawRectBar(theCtl,varCode);
  82.             }
  83.         break;
  84.         case calcCRgns:
  85.                 RectRgn((RgnHandle)(param & 0x7fffffffL), &(*theCtl)->contrlRect);
  86.         break;
  87.         case calcCntlRgn:
  88.         case calcThumbRgn:
  89.                 RectRgn((RgnHandle)(param), &(*theCtl)->contrlRect);
  90.         break;
  91.     }
  92.     
  93.     if((**theCtl).contrlData)
  94.         HSetState((**theCtl).contrlData, dState);
  95.     HSetState((Handle)theCtl, cState);
  96.  
  97.  
  98. #include "fatExit.c"
  99.  
  100.     return (0L);
  101. }
  102.  
  103. //==================================================================================
  104. // draw a simple rectangular progress bar
  105. //==================================================================================
  106.  
  107. static void drawRectBar(ControlHandle theCtl, short varCode)
  108. {
  109.     short            pDepth,left,bottom,inx;
  110.     long            range,scale,filled;
  111.     Byte            holdByte;
  112.     Rect            r;
  113.     Boolean            inColor=false;
  114.     RGBColor        saveBack,saveFore;
  115.     PenState        penSt;    
  116.     cdefHdl            hCdef;
  117.         
  118.     hCdef = (cdefHdl)(**theCtl).contrlData;
  119.     if(!hCdef)
  120.         return;
  121.         
  122.     if(!(varCode & barberPole)) {
  123.         if((**theCtl).contrlMin == 0 && (**theCtl).contrlMax == 0)
  124.             varCode ^= barberPole;
  125.     }
  126.     
  127. //----------------------------------------------------------------------------------
  128. // Initialize for drawing
  129. //----------------------------------------------------------------------------------
  130.     r = (*theCtl)->contrlRect;
  131.     InsetRect(&r,1,1);
  132.     
  133.     GetPenState(&penSt);
  134.     PenSize(1,1);
  135.     PenPat( (ConstPatternParam) "\xff\xff\xff\xff\xff\xff\xff\xff");
  136.         
  137.     pDepth = getPixDepth(&r);
  138.     if(pDepth > 2) {
  139.         saveColors(&saveFore, &saveBack);
  140.         inColor = true;    
  141.     }
  142.         
  143. //----------------------------------------------------------------------------------
  144. // frame the progress bar
  145. //----------------------------------------------------------------------------------
  146.  
  147.     FrameRect(&r);
  148.     if(inColor)
  149.         frame3DRect(&r);
  150.     InsetRect(&r,1,1);
  151.     
  152.     if(varCode & vertBar)
  153.         scale = r.bottom-r.top;
  154.     else
  155.         scale = r.right-r.left;
  156.     
  157. //----------------------------------------------------------------------------------
  158. // draw a "barber" pole status bar
  159. //----------------------------------------------------------------------------------
  160.  
  161.     if(varCode & barberPole) {
  162.         if(inColor) {
  163.             setPartColor(theCtl, cTingeLight, true);
  164.             setPartColor(theCtl, cFillPatColor, false);
  165.         }
  166.         
  167.         PenPat(&(**hCdef).thePat);
  168.         PaintRect(&r);
  169.         
  170. //----------------------------------------------------------------------------------
  171. // rotate the barber pole pattern
  172. //----------------------------------------------------------------------------------
  173.     
  174.         holdByte = (**hCdef).thePat.pat[0];
  175.         for(inx=0; inx<7; inx++)
  176.             (**hCdef).thePat.pat[inx] = (**hCdef).thePat.pat[inx+1];
  177.         (**hCdef).thePat.pat[7] = holdByte;
  178.     }
  179.     
  180. //----------------------------------------------------------------------------------
  181. // draw a regular "thermometer style" status bar
  182. //----------------------------------------------------------------------------------
  183.  
  184.     else {
  185.     
  186. //----------------------------------------------------------------------------------
  187. // calculate "filled" portion of progress bar
  188. //----------------------------------------------------------------------------------
  189.     
  190.         range = (*theCtl)->contrlMax - (*theCtl)->contrlMin;
  191.         if(range == 0)
  192.             range = 1;
  193.         filled = (*theCtl)->contrlValue * scale / range;
  194.         
  195. //----------------------------------------------------------------------------------
  196. // draw the "un-filled" portion of the progress bar
  197. //----------------------------------------------------------------------------------
  198.     
  199.         if(varCode & vertBar) {
  200.             bottom = r.bottom;
  201.             r.bottom = r.bottom-filled;                        // top portion
  202.         }
  203.         else {
  204.             left = r.left;
  205.             r.left = r.left+filled;                            // right portion
  206.         }
  207.         if(inColor) {
  208.             setPartColor(theCtl, cTingeLight, false);
  209.         }
  210.         PenPat( (ConstPatternParam) "\x00\x00\x00\x00\x00\x00\x00\x00");
  211.         PaintRect(&r);                                        // erase to bg color 
  212.  
  213. //----------------------------------------------------------------------------------    
  214. // draw the "filled" portion of the progress bar
  215. //----------------------------------------------------------------------------------
  216.         
  217.         if(varCode & vertBar) {
  218.             r.bottom = bottom;
  219.             r.top = r.bottom-filled;                        // bottom portion
  220.         }
  221.         else {
  222.             r.left = left;
  223.             r.right = r.left+filled;                        // left portion
  224.         }
  225.         if(inColor) {
  226.             setPartColor(theCtl, cFillPatColor, false);
  227.             PaintRect(&r);
  228.         }
  229.         else {
  230.             PenPat( (ConstPatternParam) "\xAA\x55\xAA\x55\xAA\x55\xAA\x55");
  231.             PaintRect(&r);
  232.         }
  233.     }
  234.     if(inColor)
  235.         restoreColors(&saveFore, &saveBack);    
  236.     SetPenState(&penSt);
  237. }
  238.  
  239. //==================================================================================
  240. // draw an round ended progress bar
  241. //==================================================================================
  242.  
  243. static void drawRoundEndBar(ControlHandle theCtl, short varCode)
  244. {
  245.     short            pDepth, diameter, inx;
  246.     Byte            holdByte;
  247.     long            range, scale, filled, unfilled, max;
  248.     Rect            r, rFill, rNoFill, rClip;
  249.     Boolean            inColor=false;
  250.     RGBColor        saveBack, saveFore;
  251.     PenState        penSt;
  252.     RgnHandle        c;    
  253.     cdefHdl            hCdef;
  254.         
  255.     hCdef = (cdefHdl)(**theCtl).contrlData;
  256.     if(!hCdef)
  257.         return;
  258.  
  259.     if(!(varCode & barberPole)) {
  260.         if((**theCtl).contrlMin == 0 && (**theCtl).contrlMax == 0)
  261.             varCode ^= barberPole;
  262.     }
  263.     
  264. //----------------------------------------------------------------------------------
  265. // Initialize for drawing
  266. //----------------------------------------------------------------------------------
  267.     rFill = (*theCtl)->contrlRect;    
  268.     InsetRect(&rFill,1,1);
  269.     
  270.     GetPenState(&penSt);
  271.     PenSize(1,1);
  272.     PenPat( (ConstPatternParam) "\xff\xff\xff\xff\xff\xff\xff\xff");
  273.     
  274.     pDepth = getPixDepth(&rFill);
  275.     if(pDepth > 2) {
  276.         saveColors(&saveFore, &saveBack);
  277.         inColor = true;    
  278.     }
  279.  
  280.     c = NewRgn();
  281.     GetClip(c);
  282.     
  283. //----------------------------------------------------------------------------------
  284. // draw the frame of the progress bar - 3D look
  285. //----------------------------------------------------------------------------------
  286.  
  287.     if(varCode & vertBar)
  288.         diameter = rFill.right - rFill.left;
  289.     else
  290.         diameter = rFill.bottom - rFill.top;
  291.  
  292.     frame3DRoundEndBar(&rFill, diameter, inColor);
  293.     InsetRect(&rFill, diameter/5, diameter/5);
  294.     r = rNoFill = rFill;
  295.     
  296. //----------------------------------------------------------------------------------
  297. // draw a "barber" pole status bar
  298. //----------------------------------------------------------------------------------
  299.  
  300.     if(varCode & barberPole) {
  301.         if(inColor) {
  302.             setPartColor(theCtl, cTingeLight, true);
  303.             setPartColor(theCtl, cFillPatColor, false);
  304.         }
  305.         PenPat(&(**hCdef).thePat);
  306.         PaintRoundRect(&rFill, diameter, diameter);
  307.         
  308. //----------------------------------------------------------------------------------
  309. // rotate the barber pole pattern
  310. //----------------------------------------------------------------------------------
  311.     
  312.         holdByte = (**hCdef).thePat.pat[0];
  313.         for(inx=0; inx<7; inx++)
  314.             (**hCdef).thePat.pat[inx] = (**hCdef).thePat.pat[inx+1];
  315.         (**hCdef).thePat.pat[7] = holdByte;
  316.     }
  317.     
  318. //----------------------------------------------------------------------------------
  319. // draw a regular "thermometer style" status bar
  320. //----------------------------------------------------------------------------------
  321.  
  322.     else {
  323.     
  324. //----------------------------------------------------------------------------------
  325. // calculate "filled" portion of progress bar
  326. //----------------------------------------------------------------------------------
  327.  
  328.         if(varCode & vertBar) {
  329.             diameter = rFill.right - rFill.left;
  330.             scale = rFill.bottom-rFill.top;
  331.         }
  332.         else {
  333.             diameter = rFill.bottom - rFill.top;
  334.             scale = rFill.right-rFill.left;
  335.         }
  336.     
  337.         range = (*theCtl)->contrlMax - (*theCtl)->contrlMin;
  338.         if(range == 0)
  339.             range = 1;
  340.         filled = (*theCtl)->contrlValue * scale / range;
  341.         max = (*theCtl)->contrlMax * scale / range;
  342.         unfilled = max-filled;
  343.         
  344. //----------------------------------------------------------------------------------
  345. // set up the rects for the "filled" and "unfilled" areas of the bar
  346. //----------------------------------------------------------------------------------
  347.     
  348.         if(varCode & vertBar) {
  349.             if(unfilled < diameter) {
  350.                 rNoFill.bottom = rNoFill.top+diameter+diameter/2;
  351.             }
  352.             else {
  353.                 rNoFill.bottom = rNoFill.top+unfilled+diameter/2;
  354.                 if(filled < diameter/2)
  355.                     rNoFill.bottom = r.bottom;
  356.             }
  357.             
  358.             if(filled < diameter) {
  359.                 rFill.top = rFill.bottom-diameter-diameter/2;
  360.             }
  361.             else {
  362.                 rFill.top = rFill.bottom-filled-diameter/2;
  363.                 if(unfilled < diameter/2)
  364.                     rFill.top = r.top;
  365.             }
  366.             rClip = rNoFill;
  367.             rClip.bottom = rClip.top+unfilled;
  368.         }
  369.         else {
  370.             if(unfilled < diameter) {
  371.                 rNoFill.left = rNoFill.right-diameter-diameter/2;
  372.             }
  373.             else {
  374.                 rNoFill.left = rNoFill.right-unfilled-diameter/2;
  375.                 if(filled < diameter/2)
  376.                     rNoFill.left = r.left;
  377.             }
  378.             
  379.             if(filled < diameter) {
  380.                 rFill.right = rFill.left+diameter+diameter/2;
  381.             }
  382.             else {
  383.                 rFill.right = rFill.left+filled+diameter/2;
  384.                 if(unfilled < diameter/2)
  385.                     rFill.right = r.right;
  386.             }
  387.             rClip = rNoFill;
  388.             rClip.left = rClip.right-unfilled;
  389.         }
  390.         
  391. //----------------------------------------------------------------------------------
  392. // draw the "unfilled" portion of the progress bar
  393. //----------------------------------------------------------------------------------
  394.     
  395.         if(inColor) {
  396.             setPartColor(theCtl, cTingeLight, false); 
  397.         }
  398.         ClipRect(&rClip);
  399.         PenPat( (ConstPatternParam) "\x00\x00\x00\x00\x00\x00\x00\x00");
  400.         PaintRoundRect(&rNoFill, diameter, diameter);
  401.     
  402. //----------------------------------------------------------------------------------    
  403. // draw the "filled" portion of the progress bar
  404. //----------------------------------------------------------------------------------
  405.     
  406.         rClip = rFill;
  407.         if(varCode & vertBar)
  408.             rClip.top = rClip.bottom-filled;
  409.         else
  410.             rClip.right = rClip.left+filled;
  411.             
  412.         ClipRect(&rClip);
  413.         
  414.         if(inColor) {
  415.             setPartColor(theCtl, cFillPatColor, false);
  416.             PaintRoundRect(&rFill, diameter, diameter);
  417.         }
  418.         else {                                                // in b&w, draw "filled"
  419.             GetPenState(&penSt);                            // portion in a gray pattern
  420.             PenPat( (ConstPatternParam) "\xAA\x55\xAA\x55\xAA\x55\xAA\x55");
  421.             PaintRoundRect(&rFill, diameter, diameter);
  422.             SetPenState(&penSt);
  423.             FrameRoundRect(&rFill, diameter, diameter);
  424.         }
  425.  
  426.         PenPat( (ConstPatternParam) "\xff\xff\xff\xff\xff\xff\xff\xff");
  427. //----------------------------------------------------------------------------------        
  428. // make it look rounded
  429. //----------------------------------------------------------------------------------
  430.     
  431.         if(inColor) {
  432.             setPartColor(theCtl, cTingeLight, true);
  433.             if(varCode & vertBar) {
  434.                 MoveTo(r.left+diameter/4, r.bottom-diameter/2);
  435.                 LineTo(r.left+diameter/4, r.top+diameter/2);
  436.             }
  437.             else {
  438.                 MoveTo(r.left+diameter/2, r.top+diameter/4);
  439.                 LineTo(r.right-diameter/2, r.top+diameter/4);
  440.             }
  441.         }
  442.     }
  443.     SetClip(c);
  444.     DisposeRgn(c);
  445.     
  446.     if(inColor)
  447.         restoreColors(&saveFore, &saveBack);
  448.     else
  449.         ForeColor(blackColor);
  450.     SetPenState(&penSt);
  451. }
  452.  
  453. //==================================================================================
  454. // frame a rect with an inset 3D effect by drawing right & bottom edges in white
  455. // and left & top in gray.
  456. //==================================================================================
  457. static void frame3DRect(Rect *r)
  458. {
  459.     RGBColor    rgbA = {0xAAAA,0xAAAA,0xAAAA},saveFore;
  460.     
  461.  
  462.  
  463.     GetForeColor(&saveFore);
  464.     RGBForeColor(&rgbA);
  465.         
  466.     MoveTo((*r).left-1,(*r).bottom);
  467.     LineTo((*r).left-1,(*r).top-1);
  468.     LineTo((*r).right,(*r).top-1);
  469.     
  470.     ForeColor(whiteColor);
  471.     Move(0,1);
  472.     LineTo((*r).right,(*r).bottom);
  473.     LineTo((*r).left,(*r).bottom);
  474.     
  475.     RGBForeColor(&saveFore);
  476. }
  477.  
  478. //==================================================================================
  479. // draw a bar with rounded ends, with a 3D effect by drawing the frame in white
  480. // from 45-225 & black from 225-45 degrees.
  481. //==================================================================================
  482. static void frame3DRoundEndBar(Rect *rr, short diameter, Boolean inColor)
  483. {
  484.     Rect        r,r2;
  485.     Boolean        vert=false;
  486.     RGBColor    rgbBack;
  487.     
  488.     if(inColor) {
  489.         GetBackColor(&rgbBack);
  490.         if(rgbBack.red == 65535 &&
  491.             rgbBack.green == 65535 &&
  492.             rgbBack.blue == 65535)
  493.             inColor = false;
  494.     }
  495.     r = r2 = *rr;
  496.     
  497.     if((r.right-r.left) < (r.bottom-r.top))
  498.         vert = true;
  499.  
  500.     if(vert) {
  501.         r2.bottom = r2.top + diameter;
  502.         if(inColor)
  503.             ForeColor(whiteColor);
  504.         FrameArc(&r2, 45, 45);
  505.         MoveTo(r.right-1, r.top+diameter/2);
  506.         LineTo(r.right-1, r.bottom-diameter/2);
  507.         r2.bottom = r.bottom;
  508.         r2.top = r.bottom-diameter;
  509.         FrameArc(&r2, 90, 135);
  510.  
  511.         ForeColor(blackColor);
  512.         FrameArc(&r2, 225, 45);
  513.         MoveTo(r.left, r.bottom-diameter/2);
  514.         LineTo(r.left, r.top+diameter/2);
  515.         r2.top = r.top;
  516.         r2.bottom = r2.top+diameter;
  517.         FrameArc(&r2, 270, 135); 
  518.     }
  519.     else {
  520.         if(inColor)
  521.             ForeColor(whiteColor);
  522.         r2.left = r2.right - diameter;
  523.         FrameArc(&r2, 45, 135);
  524.         MoveTo(r.right-diameter/2, r.bottom-1);
  525.         LineTo(r.left+diameter/2, r.bottom-1);
  526.         r2.left=r.left;
  527.         r2.right=r.left+diameter;
  528.         FrameArc(&r2, 180, 45);
  529.         
  530.         ForeColor(blackColor);
  531.         FrameArc(&r2, 225, 135);
  532.         MoveTo(r.left+diameter/2, r.top);
  533.         LineTo(r.right-diameter/2, r.top);
  534.         r2.right=r.right;
  535.         r2.left=r.right-diameter;
  536.         FrameArc(&r2, 0, 45);
  537.     }
  538. }
  539.